﻿/*
 * RETRO 2012 - v2.3
 * 
 * PaRADIIT Project
 * https://sites.google.com/site/paradiitproject/
 * 
 * This software is provided under LGPL v.3 license, 
 * which exact definition can be found at the following link:
 * http://www.gnu.org/licenses/lgpl.html
 * 
 * Please, contact us for any offers, remarks, ideas, etc.
 * 
 * Copyright © RFAI, LI Tours, 2011-2012
 * Contacts : rayar@univ-tours.fr
 *            ramel@univ-tours.fr
 * 
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.ComponentModel;
using Retro.Model.project;

namespace Retro.Model.core
{
    /// <summary>
    /// Represent a connected component created by the Clustering step
    /// </summary>
    [Serializable]
    public class Shape : INotifyPropertyChanged
    {

        #region Attributs

        private String _ShapeId;
        /// <summary>
        /// ID of the Shape (correspond to the normalized ID in alto file)
        /// </summary>
        public String ShapeId
        {
            get { return _ShapeId; }
            set
            {
                _ShapeId = value;
                NotifyPropertyChanged("ShapeId");
            }
        }


        private String _ShapePath;
        /// <summary>
        /// Path of the shapes thumbnails
        /// </summary>
        public String ShapePath
        {
            get { return _ShapePath; }
            set
            {
                _ShapePath = value;
                NotifyPropertyChanged("ShapePath");
            }
        }


        private String _ImageSourceID;
        /// <summary>
        /// Name of the source image where this shape belong 
        /// (correspond to the normalized name of Agora output)
        /// </summary>
        public String ImageSourceID
        {
            get { return _ImageSourceID; }
            set
            {
                _ImageSourceID = value;
                NotifyPropertyChanged("ImageSourceID");
            }
        }


        private String _ClusterId;
        /// <summary>
        ///  ID of the cluster
        /// </summary>
        public String ClusterId
        {
            get { return _ClusterId; }
            set
            {
                _ClusterId = value;
                NotifyPropertyChanged("ClusterId");
            }
        }


        private int _X;
        /// <summary>
        /// Top Left corner x-axis of the Shape bounding box
        /// </summary>
        public int X
        {
            get { return _X; }
            set
            {
                _X = value;
                NotifyPropertyChanged("X");
            }
        }


        private int _Y;
        /// <summary>
        ///  Top Left corner y-axis of the Shape bounding box
        /// </summary>
        public int Y
        {
            get { return _Y; }
            set
            {
                _Y = value;
                NotifyPropertyChanged("Y");
            }
        }


        private int _Height;
        /// <summary>
        /// Height of the Shape bounding box
        /// </summary>
        public int Height
        {
            get { return _Height; }
            set
            {
                _Height = value;
                NotifyPropertyChanged("Height");
            }
        }


        private int _Width;
        /// <summary>
        /// Width of the Shape bounding box
        /// </summary>
        public int Width
        {
            get { return _Width; }
            set
            {
                _Width = value;
                NotifyPropertyChanged("Width");
            }
        }

        #endregion


        #region Constructors

        /// <summary>
        /// Default Constructor
        /// </summary>
        public Shape()
        {
        }


        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="shapeID">Shape id</param>
        /// <param name="clusterID">Cluster id</param>
        /// <param name="shapeDirectory">Path of the shape exported by AGORA</param>
        /// <param name="altoDirectory">Path of the alto/ directory</param>
        public Shape(String shapeID, String clusterID, String shapeDirectory, String altoDirectory)
        {
            // Assign Shape ID
            this._ShapeId = shapeID;

            // Assign Cluster ID
            this._ClusterId = clusterID;

            // Assign Image Source
            if (shapeID.IndexOf('.') > 0)
                this._ImageSourceID = shapeID.Substring(0, shapeID.IndexOf('.'));

            // Assign Shape path
            this._ShapePath = shapeDirectory + @"\" + this._ImageSourceID + @"\" + shapeID + ".png";

            // CASE 1: On peut aller taper dans les NNNNN.connexcomp.xml
            // String altoFile = @"C:\Users\frédéric.rayar\Documents\tmp\TestData\clustering\connexcomp\BoundingBox\" + this._ImageSourceID + ".connexcomp.xml";

            // CASE 2: On peut aller taper dans les fichiers alto
            String altoFile = altoDirectory + @"\" + this._ImageSourceID + ".xml";

            // Check if XML file exist
            if (File.Exists(altoFile))
            {
                // Load the XML File
                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                doc.Load(altoFile);

                // Create an XmlNamespaceManager to resolve the default namespace.
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("alto", "http://www.loc.gov/standards/alto/ns-v2#");

                // Find the current shape
                String query = String.Format("//alto:String[@ID='{0}']", shapeID);  // or "//*[@id='{0}']" if we don't want to precise the tag name
                XmlElement ccElement = (XmlElement)doc.SelectSingleNode(query, nsmgr);

                if (ccElement != null)
                {
                    // Assign the class atributess
                    this._X = Convert.ToInt32(ccElement.Attributes["HPOS"].Value);
                    this._Y = Convert.ToInt32(ccElement.Attributes["VPOS"].Value);
                    this._Width = Convert.ToInt32(ccElement.Attributes["WIDTH"].Value);
                    this._Height = Convert.ToInt32(ccElement.Attributes["HEIGHT"].Value);
                }
            }
        }

        #endregion


        /// <summary>
        /// For Display purpose in GUI ListBox
        /// </summary>
        public override String ToString()
        {
            String description = "ID\t\t" + this.ShapeId + "\n"
                + "Size\t\t" + this._Width + "x" + this._Height;

            return description;
        }

        /// <summary>
        /// For binding purpose
        /// </summary>
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// For binding purpose
        /// </summary>
        private void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


}
